/*
 * Description: main函数。
 */
#include <tchar.h>
#include <atlstr.h>
#include <WinUser.h>
#include <cstdlib>
#include <string>
#include "dfx/app_using_report.h"
#include "log.h"
#include "error.h"
#include "agent_manager.h"
#include "common/session_utils.h"
#include "common/guest_utils.h"
#include "share_folder/share_folder_helper.h"
#include "system_log_receiver.h"
#include "performance/perf_manager.h"
#include "performance/process_monitor_injector.h"

using namespace COMMON;

namespace {
    SERVICE_STATUS_HANDLE g_serviceHandle; // 服务状态句柄
    SERVICE_STATUS g_serviceStatus; // 服务状态结构体，保存服务程序的一些信息
}

static void ServiceCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
    LOG_INFO("ServiceCtrlHandler...");
    switch (dwControl) {
        case SERVICE_CONTROL_STOP: // 暂停控制
            g_serviceStatus.dwCurrentState = SERVICE_STOPPED; // 状态设置为停止
            LOG_INFO("SERVICE_CONTROL_STOP");
            PERF_MANAGER.Stop();
            VMAGENT_MANAGER.Quit();
            LOG_INFO("quit");
            break;
        case SERVICE_CONTROL_SHUTDOWN: // 关机控制
            LOG_INFO("SERVICE_CONTROL_SHUTDOWN");
            APP_USING_REPORT.SetShutdownFlag();
            PERF_MANAGER.Stop();
            VMAGENT_MANAGER.Shutdown();
            VMAGENT_MANAGER.Quit();
            g_serviceStatus.dwCurrentState = SERVICE_STOPPED; // 状态设置为停止
            break;
        case SERVICE_CONTROL_POWEREVENT:
            LOG_INFO("SERVICE_CONTROL_POWEREVENT");
            if (dwEventType == PBT_APMSUSPEND) {  // 快速启动关闭
                LOG_INFO("quickStart_shutdown");
                APP_USING_REPORT.SetShutdownFlag();
                PERF_MANAGER.Stop();
                VMAGENT_MANAGER.QuickStartShutdown();
                VMAGENT_MANAGER.Quit();
                SHARE_FOLDER_HELPER.RemoveAllSharedFolder();
            }
            if (dwEventType == PBT_APMRESUMESUSPEND) {  // 快速启动开机
                SHARE_FOLDER_HELPER.RemoveAllSharedFolder();
                LOG_INFO("quickStart_boot");
                if (!VMAGENT_MANAGER.GustLinkInit()) {
                    LOG_ERR("GustLinkInit failed");
                }
                SYSLOGRECV_MANAGER.QuickStartInit();
                if (VMAGENT_MANAGER.Init()) {
                    LOG_ERR("VMAgent QuickStartInit failed");
                }
            }
            break;
        default:
            LOG_INFO("Something happened: {}", dwControl);
            break;
    }
    SetServiceStatus(g_serviceHandle, &g_serviceStatus);
}

static void WINAPI ServiceMain(int argc, char* argv[])
{
    LOG_INFO("ServiceMain...");
    // 初始化服务状态
    g_serviceStatus.dwServiceType = SERVICE_WIN32; // Win32类型
    g_serviceStatus.dwCurrentState = SERVICE_START_PENDING; // 当前状态为正在初始化
    // 允许停止、暂停继续、关机
    g_serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT;
    g_serviceStatus.dwWin32ExitCode = 0;
    g_serviceStatus.dwServiceSpecificExitCode = 0;
    g_serviceStatus.dwCheckPoint = 0;
    g_serviceStatus.dwWaitHint = 0;
    // 注册服务控制
    g_serviceHandle = RegisterServiceCtrlHandlerEx("vmAgent", (LPHANDLER_FUNCTION_EX)ServiceCtrlHandler, NULL);
    if (g_serviceHandle == 0) // 判断是否成功执行
    {
        g_serviceStatus.dwCurrentState = SERVICE_STOPPED;
        g_serviceStatus.dwCheckPoint = 0;
        g_serviceStatus.dwWaitHint = 0;
        LOG_ERR("RegisterServiceCtrlHandle failed: {}", GetLastError()); // 错误信息写入文件
        return;
    }
    LOG_DEBUG("RegisterServiceCtrlHandle success");  // 成功信息写入文件
    if (!VMAGENT_MANAGER.GustLinkInit()) {
        LOG_ERR("GustLinkInit failed");
    }
    g_serviceStatus.dwCurrentState = SERVICE_RUNNING; // 成功运行则把状态设置为运行状态
    SetServiceStatus(g_serviceHandle, &g_serviceStatus); // 向SCM报告服务状态
    if (!SYSLOGRECV_MANAGER.Init()) {
        LOG_INFO("Service init syslog ");
    }
    SessionUtils::Init();
    if (VMAGENT_MANAGER.Init()) {
        LOG_ERR("VMAgent execute failed");
    }
}

int main()
{
    // 设置VMAgent侧log存放路径
    std::string logName = "VMAgent";
    std::string logPath = "C:\\ProgramData\\VMAgent\\log";
    std::string logFile = logPath + "\\agent_service.log";
    if (GetFileAttributes(logPath.c_str()) == INVALID_FILE_ATTRIBUTES) {
        // 创建log目录(_mkdir创建目录成功时返回0；如果创建失败，则指定一个已存在的目录作为log存储目录)
        if (_mkdir(logPath.c_str()) != OK) {
            logFile = "C:\\Users\\Public\\agent_service.log";
        }
    }
    Log::Init(logName, logFile);
    LOG_INFO("main...");
    // FirstStart置位
    std::string flag = "FirstStart";
    if (GuestUtils::IsFirstSet(flag)) {
        LOG_INFO("First start VM");
        GuestUtils::ResetFirst(flag);
    }
    // 为当前调用的进程设置关闭的参数，此函数为进程设置一个相对于系统中其它进程的关闭顺序
    int ret = SetProcessShutdownParameters(0x3FF, 0);
    SERVICE_TABLE_ENTRY DispatchTable[2];
    std::string name = "vmAgent";
    DispatchTable[0].lpServiceName = &name[0]; // 服务程序名称
    DispatchTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; // 服务程序入口
    DispatchTable[1].lpServiceName = NULL;
    DispatchTable[1].lpServiceProc = NULL;

    // 开始服务控制分布
    if (!StartServiceCtrlDispatcher(DispatchTable)) {
        LOG_ERR("Service error: {}", GetLastError());
    }

    // 设置w32time
    if (!GuestUtils::W32timeSet()) {
        LOG_ERR("w32time set fail");
    }
    return 0;
}